package cn.vehicle.biz.impl;

import cn.vehicle.biz.CommonVehicleBiz;
import cn.vehicle.domains.bo.QueryCommonVehicleBo;
import cn.vehicle.domains.entity.CommonVehicleEntity;
import cn.vehicle.domains.vo.BasePage;
import cn.vehicle.domains.vo.req.vehicle.AddCommonVehicleReq;
import cn.vehicle.domains.vo.req.vehicle.CommonVehicleListReq;
import cn.vehicle.domains.vo.req.vehicle.UpdateCommonVehicleReq;
import cn.vehicle.domains.vo.res.vehicle.CommonVehicleRes;
import cn.vehicle.enums.VehicleTypeEnum;
import cn.vehicle.exception.VehicleAccessException;
import cn.vehicle.service.CommonVehicleService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 普通车辆业务实现类
 * <p>
 * 负责普通车辆（非运输、非厂内专用等）的新增、修改、删除、查询与分页列表等业务编排。
 * 仅进行参数校验、领域对象装配与分页封装，持久化逻辑下沉至 {@link CommonVehicleService}。
 * </p>
 *
 * <p>设计约定：</p>
 * <ul>
 *   <li>写操作统一调用 {@link CommonVehicleService}；</li>
 *   <li>新增时统一设置 {@link VehicleTypeEnum#COMMON} 类型；</li>
 *   <li>删除/更新/查询前统一进行存在性校验，异常使用 {@link VehicleAccessException} 抛出。</li>
 * </ul>
 */
@Service
public class CommonVehicleBizImpl implements CommonVehicleBiz {

    @Resource
    private CommonVehicleService commonVehicleService;

    /**
     * 新增普通车辆
     *
     * @param req 新增请求参数
     *            方法内仅完成属性拷贝与车辆类型设置，实际入库由 {@link CommonVehicleService#addCommonVehicle(CommonVehicleEntity)} 执行。
     */
    @Override
    public void addCommonVehicle(AddCommonVehicleReq req) {
        // 装配领域实体：避免直接在 Service 层处理 VO
        CommonVehicleEntity commonVehicleEntity = new CommonVehicleEntity();
        // 将请求参数拷贝到实体（字段名/类型需兼容）
        BeanUtils.copyProperties(req, commonVehicleEntity);

        // 统一设置普通车辆类型：COMMON
        commonVehicleEntity.setVehicleType(VehicleTypeEnum.COMMON.name());

        // 调用 Service 落库
        commonVehicleService.addCommonVehicle(commonVehicleEntity);
    }

    /**
     * 更新普通车辆
     *
     * <p>先进行存在性校验，再进行属性拷贝与更新。</p>
     *
     * @param req 更新请求参数，需包含主键ID
     * @throws VehicleAccessException 车辆不存在时抛出
     */
    @Override
    public void updateCommonVehicle(UpdateCommonVehicleReq req) {
        checkCommonVehicleExist(req.getId());

        CommonVehicleEntity updateEntity = new CommonVehicleEntity();
        BeanUtils.copyProperties(req, updateEntity);
        commonVehicleService.updateCommonVehicle(updateEntity);
    }

    /**
     * 校验普通车辆是否存在
     *
     * @param id 车辆主键ID
     * @return 已存在的车辆实体
     * @throws VehicleAccessException 不存在时抛出 DATE_NOT_EXIST
     */
    private CommonVehicleEntity checkCommonVehicleExist(Long id) {
        CommonVehicleEntity commonVehicleEntity = commonVehicleService.getCommonVehicleById(id);

        if (commonVehicleEntity == null) {
            throw VehicleAccessException.DATE_NOT_EXIST.newInstance("车辆不存在");
        }

        return commonVehicleEntity;
    }

    /**
     * 删除普通车辆
     *
     * @param id 车辆主键ID
     * @throws VehicleAccessException 车辆不存在时抛出
     */
    @Override
    public void deleteCommonVehicle(Long id) {
        checkCommonVehicleExist(id);

        commonVehicleService.deleteCommonVehicle(id);
    }


    /**
     * 根据ID查询普通车辆详情
     *
     * @param id 车辆主键ID
     * @return 车辆详情响应对象
     * @throws VehicleAccessException 车辆不存在时抛出
     */
    @Override
    public CommonVehicleRes getCommonVehicleById(Long id) {
        CommonVehicleEntity commonVehicleEntity = checkCommonVehicleExist(id);

        CommonVehicleRes commonVehicleRes = new CommonVehicleRes();
        BeanUtils.copyProperties(commonVehicleEntity, commonVehicleRes);
        return commonVehicleRes;
    }

    @Override
    public BasePage<CommonVehicleRes> listCommonVehicles(CommonVehicleListReq req) {
        // 启动分页：仅拦截下一次查询（selectCommonVehicleList）
        Page<CommonVehicleEntity> page = PageHelper.startPage(req.getPageNo(), req.getPageSize());


        // 组装查询 BO，避免将请求对象直接透传到 Service
        QueryCommonVehicleBo queryCommonVehicleBo = new QueryCommonVehicleBo();
        // 拷贝筛选条件（pageNo/pageSize 无需拷贝至 BO）
        BeanUtils.copyProperties(req, queryCommonVehicleBo);


        List<CommonVehicleEntity> commonVehicleEntityList = commonVehicleService.selectCommonVehicleList(queryCommonVehicleBo);
        List<CommonVehicleRes> list = commonVehicleEntityList.stream().map(commonVehicleEntity -> {
            CommonVehicleRes commonVehicleRes = new CommonVehicleRes();
            // DO: 实体 → 响应对象拷贝
            BeanUtils.copyProperties(commonVehicleEntity, commonVehicleRes);

            return commonVehicleRes;
        }).toList();
        // 封装分页结果：总页数、总条数、当前页数据
        return BasePage.generateResult(page.getPages(), page.getTotal(), list);
    }
}
